package com.ueboot.weishop.api.controller.coupon;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.ueboot.core.exception.BusinessException;
import com.ueboot.core.http.response.Response;
import com.ueboot.weishop.api.SessionUtils;
import com.ueboot.weishop.api.controller.coupon.vo.CouponReq;
import com.ueboot.weishop.api.controller.coupon.vo.CouponResp;
import com.ueboot.weishop.api.controller.coupon.vo.FindResp;
import com.ueboot.weishop.api.mq.config.QueuesType;
import com.ueboot.weishop.api.mq.receiver.dto.CouponMessageDto;
import com.ueboot.weishop.entity.activity.ActivityAttrEntity;
import com.ueboot.weishop.entity.activity.ActivityEntity;
import com.ueboot.weishop.entity.customer.CustomerCouponEntity;
import com.ueboot.weishop.entity.user.CusGroup;
import com.ueboot.weishop.entity.user.OilVin;
import com.ueboot.weishop.service.activity.ActivityAttrService;
import com.ueboot.weishop.service.activity.ActivityService;
import com.ueboot.weishop.service.cache.CacheService;
import com.ueboot.weishop.service.customer.CustomerCouponService;
import com.ueboot.weishop.service.user.CusGroupService;
import com.ueboot.weishop.service.user.OilVinService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

/**
 * @author Neel
 * @date 2017/12/3
 */
@Slf4j
@RestController
@RequestMapping(value = "/api/private/coupon")
public class CouponController {

	@Autowired
	private ActivityService activityService;

	@Autowired
	private ActivityAttrService activityAttrService;

	@Autowired
	private CacheService cacheService;

	@Autowired
	private CustomerCouponService customerCouponService;

	@Autowired
	private OilVinService oilVinService;

	@Autowired
	private CusGroupService cusGroupService;

	@Autowired
	private AmqpTemplate amqpTemplate;


	@RequestMapping(value = "/submit", method = RequestMethod.POST)
	public Response<CouponResp> submit(@RequestBody CouponReq req) {
		String openId = SessionUtils.getOpenId();

		if (StringUtils.isEmpty(req.getDealer())) {
			throw new BusinessException("请选择经销商");
		}

		if (StringUtils.isEmpty(req.getVin())) {
			throw new BusinessException("100001", "请认证");
		}


		ActivityEntity activityEntity = this.activityService.findBySn(req.getSn());
		Date now = new Date();


		if (activityEntity == null || now.before(activityEntity.getStartTime()) || now.after(activityEntity.getEndTime())) {
			throw new BusinessException("不在活动中");
		}

		ActivityAttrEntity couponAmountAttr = null;
		ActivityAttrEntity couponProjectCodeAttr = null;
		ActivityAttrEntity couponActualCountAttr = null;
		ActivityAttrEntity couponCustomerTypeAttr = null;
		ActivityAttrEntity couponStartDateAttr = null;
		ActivityAttrEntity couponEndDateAttr = null;

		List<ActivityAttrEntity> activityAttrs = activityAttrService.findBySn(req.getSn());

		for (ActivityAttrEntity attrEntity : activityAttrs) {
			if ("couponAmount".equals(attrEntity.getKeyName())) {
				couponAmountAttr = attrEntity;
				continue;
			}
			if ("couponProjectCode".equals(attrEntity.getKeyName())) {
				couponProjectCodeAttr = attrEntity;
				continue;
			}
			if ("couponActualCount".equals(attrEntity.getKeyName())) {
				couponActualCountAttr = attrEntity;
				continue;
			}
			if ("couponCustomerType".equals(attrEntity.getKeyName())) {
				couponCustomerTypeAttr = attrEntity;
				continue;
			}
			if ("couponStartDate".equals(attrEntity.getKeyName())) {
				couponStartDateAttr = attrEntity;
				continue;
			}
			if ("couponEndDate".equals(attrEntity.getKeyName())) {
				couponEndDateAttr = attrEntity;
				continue;
			}
		}

		if (couponAmountAttr == null || couponProjectCodeAttr == null || couponActualCountAttr == null || couponCustomerTypeAttr == null) {
			throw new BusinessException("活动参数配置有误，请联系客服");
		}
		//缓存代金券领取数量的key
		String countKey = activityEntity.getGroupCode() + "|" + couponCustomerTypeAttr.getValue();
		//缓存是否已购买的key
		String countVinKey = countKey + req.getVin();


		//判断用户是否领取过该类代金券
		Integer vinBuyCount = cacheService.getAlreadyBuyCount(req.getSn(), countVinKey);
		if (vinBuyCount != null && vinBuyCount.intValue() >= activityEntity.getLimitCopies().intValue()) {
			throw new BusinessException("100002", "超过领取次数");
		}

		//判断该用户是不是具有该类代金券的领取资格（是不是该类用户）
		String customerType = couponCustomerTypeAttr.getValue();
		if (customerType.equals(ActivityAttrEntity.CUSTOMER_TYPE_OIL)) {
			//判断半合成机油用户
			OilVin oilVin = oilVinService.findByVin(req.getVin());
			if (oilVin != null) {
				throw new BusinessException("您没有该代金券的领取资格");
			}
		} else {
			CusGroup cusGroup = cusGroupService.findByVin(req.getVin());
			if (cusGroup != null && !cusGroup.getGroupName().equals(customerType)) {
				throw new BusinessException("您没有该代金券的领取资格");
			}
			//判断是否是A、B、C类用户，如都不满足，则归C类用户
			if (cusGroup == null && !customerType.equals(ActivityAttrEntity.CUSTOMER_TYPE_C)) {
				throw new BusinessException("您没有该代金券的领取资格");
			}
		}


		Integer buyCount = cacheService.getAlreadyBuyCount(req.getSn(), countKey);
		int count = buyCount == null ? 0 : buyCount.intValue();
		int totalCount = couponActualCountAttr.getValue() == null ? 0 : Integer.parseInt(couponActualCountAttr.getValue());
		//已经领完
		if (count >= totalCount) {
			throw new BusinessException("OVER", "超过领取总数");
		}
		//当总数量大于已领用数量，进行领用
		Long index = cacheService.incrAlreadyBuyCount(req.getSn(), countKey, 1L);
		if (index > totalCount) {
			throw new BusinessException("OVER", "超过领取总数");
		}
		try {
			cacheService.incrAlreadyBuyCount(req.getSn(), countVinKey, 1L);
		} catch (Exception e) {
			cacheService.incrAlreadyBuyCount(req.getSn(), countKey, -1L);
		}

		try {
			//判断是否已经领取了
			List<CustomerCouponEntity> customerCouponEntities = customerCouponService.findByVinAndSource(req.getVin(), activityEntity.getGroupCode(), couponCustomerTypeAttr.getValue());
			if (customerCouponEntities.size() >= activityEntity.getLimitCopies().intValue()) {
				throw new BusinessException("OVER", "数据库超过领取次数");
			}
			CouponMessageDto dto = new CouponMessageDto();
			dto.setCustomerOpenId(openId);
			dto.setActName(activityEntity.getName());
			dto.setActGroupCode(activityEntity.getGroupCode());
			dto.setCustomerType(couponCustomerTypeAttr.getValue());
			dto.setVin(req.getVin());
			dto.setDealer(req.getDealer());
			dto.setProjectCode(couponProjectCodeAttr.getValue());
			dto.setAmount(couponAmountAttr.getValue() == null ? 0 : Integer.parseInt(couponAmountAttr.getValue()));
			dto.setBeginDate(couponStartDateAttr == null ? null : couponStartDateAttr.getValue());
			dto.setEndDate(couponEndDateAttr == null ? null : couponEndDateAttr.getValue());
			amqpTemplate.convertAndSend(QueuesType.COUPON_SAVE_SYNC, JSON.toJSONString(dto));
			log.info("提交MQ成功，等待入库");
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			//还原被扣库存
			cacheService.incrAlreadyBuyCount(req.getSn(), countKey, -1L);
			cacheService.incrAlreadyBuyCount(req.getSn(), countVinKey, -1L);
			throw new BusinessException("代金券领取失败");
		}
		CouponResp resp = new CouponResp();
		resp.setActivityId(activityEntity.getId());
		resp.setAmount(couponAmountAttr.getValue() == null ? 0 : Integer.parseInt(couponAmountAttr.getValue()));
		resp.setDealer(req.getDealer());
		resp.setSn(activityEntity.getSn());
		resp.setVin(req.getVin());
		resp.setDealerName(req.getDealerName());
		resp.setExpiredDate(couponEndDateAttr.getValue());
		resp.setName(activityEntity.getName());

		return new Response<>(resp);
	}


	@RequestMapping(value = "/find", method = RequestMethod.POST)
	public Response<List<FindResp>> find() {
		String openId = SessionUtils.getOpenId();

		if (StringUtils.isEmpty(openId)) {
			throw new BusinessException("请使用微信");
		}
		//当总数量大于已
		List<FindResp> respList = Lists.newLinkedList();
		List<CustomerCouponEntity> customerCouponList = customerCouponService.findByCustomerOpenId(openId);
		customerCouponList.forEach(coupon -> {
			FindResp resp = new FindResp();
			BeanUtils.copyProperties(coupon, resp);
			resp.setName(coupon.getName());
			resp.setSource(coupon.getSource());
			resp.setAmount(coupon.getAmount() / 100);
			respList.add(resp);
		});
		return new Response<>(respList);
	}

}
